package com.xiaolin.service;

import com.xiaolin.config.TimestampToDateMorpher;
import com.xiaolin.po.BulletScreen;
import com.xiaolin.po.Video;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class HttpService {

    @Autowired
    private VideoSerivce videoSerivce;

    @Autowired
    private BulletScreenSerivce bulletScreenSerivce;

    /**
     * 通过aid查询弹幕
     *
     * @param cid
     * @throws Exception
     */
    private void finBulletScreen(Integer cid, Integer aid){
        ResponseEntity<String> forEntity = restTemplate.getForEntity("https://api.bilibili.com/x/v1/dm/list.so?oid=" + cid, String.class);

        String en1 = forEntity.getBody();

        String c = "<d p=\"(.*?)</d>";
        Pattern a = Pattern.compile(c);
        Matcher m = a.matcher(en1);
        while (m.find()) {
            String speak = m.group().replace("<d p=\"", "");
            speak = speak.replace("</d>", "");

            String[] split = speak.split("\">");

            String[] pList = split[0].split(",");

            long l = Long.parseLong(pList[4] + "000");
            Date setSendDate = new Date(l);
            BulletScreen bulletScreen = new BulletScreen();
            bulletScreen.setAid(aid);
            bulletScreen.setId(Long.parseLong(pList[7]));
            bulletScreen.setData(pList[6]);
            bulletScreen.setMid(Integer.parseInt(pList[3]));
            bulletScreen.setSendDate(setSendDate);
            bulletScreen.setTimestamp(Double.parseDouble(pList[0]));
            bulletScreen.setText(split[1]);

            try {
                bulletScreenSerivce.insert(bulletScreen);
            } catch (Exception e) {
                System.out.println("评论写入出错: ==> " + bulletScreen);
            }
        }

    }

    /**
     * 视频爬虫入口
     *
     * @param aid
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void start(Integer aid) throws Exception {
        findAV(aid);

    }

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 通过aid查询视频
     *
     * @param aid
     * @throws Exception
     */
    private void findAV(Integer aid){
        ResponseEntity<String> forEntity;
        try {
            forEntity = restTemplate.getForEntity("https://www.bilibili.com/video/av" + aid, String.class);
        } catch (Exception e) {
            return;
        }
        String en = forEntity.getBody();

        if (en.contains("<title>出错啦! - bilibili.com</title>") || en.contains("<title data-vue-meta=\"true\">视频去哪了呢？_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili</title>")) {
            System.out.println("爬到: ===> " + aid + " <== 不存在或出错了!");
            return;
        }


        String con = "<script>window.__INITIAL_STATE__=\\{(.*)?\\};\\(function\\(\\)\\{var s;";
        Pattern ah = Pattern.compile(con);
        Matcher mr = ah.matcher(en);
        while (mr.find()) {
            //获得视频数据json
            String json = mr.group();

            if (!json.contains("videoData")) {
                System.out.print("时间:" + new Date().toLocaleString() + " ");
                System.out.println("找不到videoData ===> " + json);
                continue;
            }
//            System.out.println(json);

            //处理json
            json = json.replace("<script>window.__INITIAL_STATE__=", "");
            json = json.replace(";(function(){var s;", "");

            JSONObject jsonObject = JSONObject.fromObject(json);

            //反序列化视频信息
            JSONObject videoDataJson = jsonObject.getJSONObject("videoData");

            Object id = videoDataJson.get("aid");

//            System.out.println( "爬到: ===> " +  id);
            if (id == null || id.equals(aid + "")) {
                System.out.print("时间:" + new Date().toLocaleString() + " ");
                System.out.println("获取不到id: ===> " + id + " <===> " + json);
                continue;
            }

            videoDataJson.remove("rights");
            videoDataJson.remove("owner");
            videoDataJson.remove("stat");
            videoDataJson.remove("dimension");
            videoDataJson.remove("subtitle");
            videoDataJson.remove("pages");

            JSONUtils.getMorpherRegistry().registerMorpher(new TimestampToDateMorpher());

          //  Video video = (Video) JSONObject.toBean(videoDataJson, Video.class);
            Video video = com.alibaba.fastjson.JSONObject.parseObject(com.alibaba.fastjson.JSONObject.toJSONString(videoDataJson), Video.class);
//            System.out.println(video);
            int insert = videoSerivce.insert(video);

            if (insert == 0) {
                System.out.print("时间:" + new Date().toLocaleString() + " ");
                System.out.println("保存失败 ==> " + id);
            }

            //查询弹幕
            finBulletScreen(video.getCid(), aid);

//            JSONObject upDataJson = jsonObject.getJSONObject("upData");
//            upDataJson.remove("level_info");
//            upDataJson.remove("pendant");
//            upDataJson.remove("nameplate");
//            upDataJson.remove("Official");
//            upDataJson.remove("official_verify");
//            upDataJson.remove("vip");
//            upDataJson.remove("attentions");
//            upDataJson.remove("DisplayRank");
//            Up up = (Up) JSONObject.toBean(upDataJson, Up.class);
//            System.out.println(up);


        }

    }


}
